use teloxide::{
    prelude::*,
    requests::{Requester, ResponseResult},
    types::{ChatId, Message},
    utils::command::BotCommands,
};

#[derive(BotCommands, Clone)]
#[command[rename_rule = "lowercase", description = "These commands are supported:"]]
enum Command {
    #[command(description = "display this text")]
    Help,
    #[command(description = "handle a username")]
    Username(String),
    #[command(description = "handle a username and an age", parse_with = "split")]
    UsernameAndAge { username: String, age: u8 },
}

pub struct MyBot {
    bot: Bot,
}

impl MyBot {
    pub async fn new(token: String) -> Self {
        let bot = Bot::new(token);
        log::info!("Started new bot");
        MyBot { bot }
    }
    pub async fn run(&self) {
        let handler = dptree::entry()
            .branch(Update::filter_message().endpoint(Self::answer_msg))
            .branch(
                Update::filter_message()
                    .filter_command::<Command>()
                    .endpoint(Self::answer_cmd),
            );
        Dispatcher::builder(self.bot.clone(), handler)
            .enable_ctrlc_handler()
            .build()
            .dispatch()
            .await;
        // Command::repl(self.bot.clone(), Self::answer).await;
    }

    async fn answer_msg(bot: Bot, msg: Message) -> ResponseResult<()> {
        const ADMINS: [ChatId; 2] = [ChatId(248770879), ChatId(395543883)];
        if ADMINS.contains(&msg.chat.id) {
            if let Some(reply_to_message) = msg.reply_to_message() {
                println!("Reply to message: {:?}", reply_to_message);
                //TODO: Проверить можно ли получить отправителя пересланного сообщения
            } else {
                println!("Received a regular message");
            }
        } else {
            for admin in ADMINS.iter() {
                let uname = msg.chat.username().unwrap_or_else(|| "");
                let from_user = if uname == "" {
                    msg.chat.id.to_string()
                } else {
                    "@".to_string() + &uname.to_string().clone()
                };
                let msg_to_admin = format!("Вам пришло новое сообщение от {from_user}");
                bot.send_message(admin.clone(), msg_to_admin).await?;
                bot.forward_message(admin.clone(), msg.chat.id, msg.id)
                    .await?;
            }
            bot.send_message(
                msg.chat.id,
                format!("Ваше сообщение было отправлено админам!"),
            )
            .reply_to_message_id(msg.id)
            .await?;
        }
        Ok(())
    }

    async fn answer_cmd(bot: Bot, msg: Message, cmd: Command) -> ResponseResult<()> {
        match cmd {
            Command::Help => {
                bot.send_message(msg.chat.id, Command::descriptions().to_string())
                    .reply_to_message_id(msg.id)
                    .await?
            }
            Command::Username(username) => {
                bot.send_message(msg.chat.id, format!("Your username is @{username}"))
                    .await?
            }
            Command::UsernameAndAge { username, age } => {
                bot.send_message(
                    msg.chat.id,
                    format!("Your username is @{username} and age is {age}"),
                )
                .await?
            }
        };
        Ok(())
    }
}
